---
description: Steps required to deploy SaaS Boilerplate on AWS
---

import ProjectName from '../../shared/components/ProjectName.component';

# Step 3: Initialize an environment stage

<ProjectName /> provides the ability to deploy various versions of your
application, such as QA, staging, or production. You have the flexibility to
determine their naming conventions and the number of environments required. The
only exception is the `local` environment, which is a specialized preconfigured
environment utilized for running
<ProjectName /> on local machine.

All environments can either be deployed to a single AWS account or to separate ones, depending on your cloud governance
policies and preferences.

In essence, they are defined through different environmental variables. To manage these variables, the <ProjectName/>
leverages AWS Systems Manager Parameter Store and a tool called [`chamber`](https://github.com/segmentio/chamber).
With these tools, managing environment variables is easy and secure.

:::caution

Before deploying the infrastructure to AWS, you must set all required environmental variables!

:::

## Install chamber CLI

Follow the [official instructions](https://github.com/segmentio/chamber#installing) on how to install chamber.

## Bootstrap CDK

In <ProjectName/>, AWS CDK is used to define infrastructure as a code. It also needs to create a KMS key with alias
`parameter_store_key` that `chamber` is using to manage secure values.

Before you deploy anything to AWS you need to run following initialization command:

```shell
pnpm saas infra bootstrap
```

If you're deploying a second environment stage to the
same AWS account as the previous one you will receive an information that bootstrap has already been run.

## Set required env variables in SSM Parameter Store

Open a shell terminal with proper AWS credentials available. If you followed a
[previous step](./configure-aws-credentials) you can run following command to do it:

```shell
pnpm saas aws set-env [STAGE_NAME]
```

Let's assume your stage is named `qa` and the project is named `saas`.
Here's a list of all required env variables that you should set and a command that you should use to set them.

### Set project name

Each stage can have a different project name if you want but recommended approach is to use the same across all stages.

```shell
pnpm saas aws set-var PROJECT_NAME saas
```

### Configure domains

For this step you'll need the hosted zone parameters that you acquired in the previous step of this guide.

```shell
pnpm saas aws set-var SB_HOSTED_ZONE_ID XYZ
pnpm saas aws set-var SB_HOSTED_ZONE_NAME example.com
pnpm saas aws set-var SB_DOMAIN_ADMIN_PANEL admin.qa.example.com
pnpm saas aws set-var SB_DOMAIN_FLOWER flower.qa.example.com
pnpm saas aws set-var SB_DOMAIN_API api.qa.example.com
pnpm saas aws set-var SB_DOMAIN_CDN cdn.qa.example.com
pnpm saas aws set-var SB_DOMAIN_DOCS docs.qa.example.com
pnpm saas aws set-var SB_DOMAIN_WEB_APP app.qa.example.com
```

:::info
`SB_HOSTED_ZONE_ID` and `SB_HOSTED_ZONE_NAME` can be skipped if you are using externally managed DNS. In that case,
certificates for CloudFront distribution and Load Balancer should be already generated, and their ARNs provided in
`SB_CLOUDFRONT_CERTIFICATE_ARN` and `SB_LOAD_BALANCER_CERTIFICATE_ARN` parameters. As the last step,
CNAME DNS records pointing to CloudFront distribution and Load Balancer need to be manually added.
:::

### \[Optional\] Configure production domain

<ProjectName /> creates a certificate that supports `*.[ENV_STAGE].example.com` domains, like
`app.production.example.com`. You most likely don't want such domain and need straight up `app.example.com` for your
production environment. Set a following variable to override the default behaviour:

```
pnpm saas aws set-var SB_CERTIFICATE_DOMAIN example.com
```

Without setting this variable you'll encounter an error during deployment
```
Resource handler returned message: "Invalid request provided: AWS::CloudFront::Distribution: The certificate that is
attached to your distribution doesn't cover the alternate domain name (CNAME) that you're trying to add.
```

### [Optional] Configuring CI mode

:::caution
Deploying `<ProjectName />` on a **new AWS account** may result in reaching the AWS CodeBuild concurrent build limit.
This is a common issue with newly created AWS accounts. To mitigate potential issues during CI builds, it is advisable
to configure the CI mode to `simple`. For more information about potential issues with new AWS accounts, see
[Configuring AWS Credentials for New Accounts](./configure-aws-credentials#for-users-with-newly-created-aws-accounts).
:::

Changing the CI mode affects the execution behavior of CI processes:
- `parallel` (the default setting): Enables actions in the AWS CodePipeline stages to execute concurrently.
- `simple`: Ensures actions in the AWS CodePipeline stages are executed sequentially, with only one CodeBuild process
running at a time.

We recommend utilizing the `parallel` mode for optimal performance and efficiency, provided that the concurrent build
limits of AWS CodeBuild have been adjusted accordingly.

```shell
pnpm saas aws set-var SB_CI_MODE <parallel/simple>
```

:::info
Note: If you modify the settings for an already deployed environment, it is necessary to
[redeploy the CI stack](./deploy-infrastructure#deploy-the-infrastructure) to ensure that the changes take effect.
:::

### \[Optional\] Protect the website with basic auth

It's a good idea to prevent unauthorized access to staging environments so we suggest to set a basic auth password
if this isn't a production environment.

```shell
pnpm saas aws set-var SB_BASIC_AUTH username:password
```

### \[Optional\] Set tools env variables

The `tools` package during CI deployment is responsible for uploading the information of the version of deployed
application on specific environment. Then, you will be able to check currently deployed state in the
[version matrix](../../../working-with-sb/dev-tools/version-matrix).

To configure `tools` package env variables follow the example below.

```shell
pnpm saas aws set-var SB_TOOLS_ENABLED <true/false>
pnpm saas aws set-var SB_TOOLS_BASIC_AUTH username:password
pnpm saas aws set-var SB_TOOLS_HOSTED_ZONE_ID XYZ
pnpm saas aws set-var SB_TOOLS_HOSTED_ZONE_NAME example.com
pnpm saas aws set-var SB_TOOLS_DOMAIN_VERSION_MATRIX status.example.com
```

:::info

If you set `SB_TOOLS_ENABLED` to `true` make sure to deploy **version matrix** component before first CI pipeline run.

Follow the [deployment instructions](../../../working-with-sb/dev-tools/version-matrix#deployment) for more details.

:::

## Env variable validation

You can look up the validator in `packages/internal/cli/src/config/env.ts`, which runs on every `nx` command that
is executed. It will throw an error if you forget to set any required variables. Feel free to add other variables in
there if you need.
